/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */

package com.github.pig.gateway.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;

import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.github.pig.common.vo.MenuVO;
import com.github.pig.gateway.feign.MenuService;
import com.github.pig.gateway.service.PermissionService;
import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.util.StrUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lengleng
 * @date 2017/10/28
 */
@Slf4j
@Service("permissionService")
public class PermissionServiceImpl implements PermissionService {
	@Autowired
	private MenuService menuService;

	private AntPathMatcher antPathMatcher = new AntPathMatcher();

	@Override
	public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
		// ele-admin options 跨域配置，现在处理是通过前端配置代理，不使用这种方式，存在风险
		// if (HttpMethod.OPTIONS.name().equalsIgnoreCase(request.getMethod())) {
		// return true;
		// }
		Object principal = authentication.getPrincipal();
		List<SimpleGrantedAuthority> grantedAuthorityList = (List<SimpleGrantedAuthority>) authentication
				.getAuthorities();
		boolean hasPermission = false;

		if (principal != null) {
			if (CollUtil.isEmpty(grantedAuthorityList)) {
				log.warn("角色列表为空：{}", authentication.getPrincipal());
				return hasPermission;
			}

			Set<MenuVO> urls = new HashSet<>();
			for (SimpleGrantedAuthority authority : grantedAuthorityList) {
				if (!StrUtil.equals(authority.getAuthority(), "ROLE_USER")) {
					Set<MenuVO> menuVOSet = menuService.findMenuByRole(authority.getAuthority());
					if (CollUtil.isNotEmpty(menuVOSet)) {
						CollUtil.addAll(urls, menuVOSet);
					}
				}
			}

			for (MenuVO menu : urls) {
				if (StringUtils.isNotEmpty(menu.getUrl())
						&& antPathMatcher.match(menu.getUrl(), request.getRequestURI())
						&& request.getMethod().equalsIgnoreCase(menu.getMethod())) {
					hasPermission = true;
					break;
				}
			}
		}
		return hasPermission;
	}
}
